package com.ruoyi.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;

import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.domain.SpffUserRelations;
import com.ruoyi.system.domain.SpffUsers;
import com.ruoyi.system.service.ISpffUserRelationsService;
import com.ruoyi.system.service.ISpffUsersService;
import com.ruoyi.user.dto.LoginFormDTO;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.user.dto.UserDTO;
import com.ruoyi.user.mapper.UserMapper;
import com.ruoyi.user.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.BitFieldSubCommands;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;



/**

 */
@Slf4j
@Service
public class UserServiceImpl implements IUserService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private ISpffUsersService spffUsersService;

    @Autowired
    private ISpffUserRelationsService spffUserRelationsService;

    @Autowired
    private TokenService tokenService;
    @Override
    public AjaxResult login(LoginFormDTO loginForm, HttpSession session) {
        if(loginForm==null){
            return AjaxResult.error("请输入账号和密码");
        }
        SpffUsers user = spffUsersService.selectSpffUsersByUsername(loginForm.getUsername());

        if(user == null){
            return AjaxResult.error("用户名或密码错误");
        }

        if(!user.getPassword().equals(loginForm.getPassword())){
            return AjaxResult.error("用户名或密码错误");
        }

        // 使用与管理端统一的Token机制
        SysUser sysUser = new SysUser();
        sysUser.setUserId(user.getId());
        sysUser.setUserName(user.getUsername());
        sysUser.setPassword(user.getPassword());

        // 创建LoginUser对象，使用包含SysUser的构造函数
        LoginUser loginUser = new LoginUser();
        loginUser.setUserId(user.getId());
        loginUser.setUser(sysUser);

        // 使用TokenService创建Token，与管理端保持一致
        String token = tokenService.createToken(loginUser);
        log.info("用户登录成功，当前用户:{} , 生成Token：{}", user.getUsername(),token);
        HashMap map = new HashMap<>();
        map.put("token", token);
        map.put("user", user);
        return AjaxResult.success(map);
    }

    @Override
    public AjaxResult getUserInfo(Long userId) {

        SpffUsers user = spffUsersService.selectSpffUsersById(userId);
        if (user == null) {
            return AjaxResult.error("用户不存在");
        }
        return AjaxResult.success(user);
    }

    @Override
    public AjaxResult updateUserInfo(SpffUsers user) {
        if (user.getId() == null) {
            return AjaxResult.error("用户ID不能为空");
        }

        SpffUsers existingUser = spffUsersService.selectSpffUsersById(user.getId());
        if (existingUser == null) {
            return AjaxResult.error("用户不存在");
        }

        // 只允许更新部分字段
        existingUser.setNickname(user.getNickname());
        existingUser.setAvatar(user.getAvatar());
        existingUser.setPhone(user.getPhone());
        existingUser.setEmail(user.getEmail());
        existingUser.setGender(user.getGender());
        existingUser.setBirthday(user.getBirthday());
        existingUser.setLocation(user.getLocation());
        existingUser.setLatitude(user.getLatitude());
        existingUser.setLongitude(user.getLongitude());
        existingUser.setBio(user.getBio());

        spffUsersService.updateSpffUsers(existingUser);
        return AjaxResult.success("用户信息更新成功");
    }

    @Override
    public AjaxResult followUser(Long userId, Long targetUserId) {
        if (userId.equals(targetUserId)) {
            return AjaxResult.error("不能关注自己");
        }

        SpffUsers targetUser = spffUsersService.selectSpffUsersById(targetUserId);
        if (targetUser == null) {
            return AjaxResult.error("目标用户不存在");
        }

        SpffUserRelations existingRelation = spffUserRelationsService.selectByUserIdAndTargetUserId(userId, targetUserId, 1);
        if (existingRelation != null) {
            return AjaxResult.error("已经关注过该用户");
        }
        // 新增关注记录
        SpffUserRelations relation = new SpffUserRelations();
        relation.setUserId(userId);
        relation.setTargetUserId(targetUserId);
        relation.setRelationType(1); // 1表示关注
        spffUserRelationsService.insertSpffUserRelations(relation);
        // 更新被关注用户的粉丝数
        targetUser.setFollowerCount(targetUser.getFollowerCount() + 1);
        spffUsersService.updateSpffUsers(targetUser);

        return AjaxResult.success("关注成功");
    }

    @Override
    public AjaxResult unfollowUser(Long userId, Long targetUserId) {
        if (userId.equals(targetUserId)) {
            return AjaxResult.error("不能取消关注自己");
        }

        SpffUsers targetUser = spffUsersService.selectSpffUsersById(targetUserId);
        if (targetUser == null) {
            return AjaxResult.error("目标用户不存在");
        }

        SpffUserRelations existingRelation = spffUserRelationsService.selectByUserIdAndTargetUserId(userId, targetUserId, 1);
        
        if (existingRelation == null) {
            return AjaxResult.error("未关注该用户");
        }

        // 删除关注关系
        spffUserRelationsService.deleteByUserIdAndTargetUserId(userId, targetUserId, 1);

        // 更新被关注用户的粉丝数
        if (targetUser.getFollowerCount() > 0) {
            targetUser.setFollowerCount(targetUser.getFollowerCount() - 1);
            spffUsersService.updateSpffUsers(targetUser);
        }

        return AjaxResult.success("取消关注成功");
    }

    @Override
    public AjaxResult getFollowers(Long userId, Integer page, Integer pageSize) {
        SpffUsers user = spffUsersService.selectSpffUsersById(userId);
        if (user == null) {
            return AjaxResult.error("用户不存在");
        }

        // 查询粉丝列表
        Map<String, Object> params = new HashMap<>();
        params.put("userId", userId);
        params.put("offset", (page - 1) * pageSize);
        params.put("pageSize", pageSize);
        
        List<SpffUserRelations> relations = spffUserRelationsService.selectFollowersByUserId(params);
        int total = spffUserRelationsService.countFollowersByUserId(userId);

        if (relations.isEmpty()) {
            Map<String, Object> result = new HashMap<>();
            result.put("list", new ArrayList<>());
            result.put("total", total);
            result.put("page", page);
            result.put("pages", total == 0 ? 0 : (int) Math.ceil((double) total / pageSize));
            return AjaxResult.success(result);
        }

        // 获取粉丝用户ID列表
        List<Long> followerUserIds = relations.stream()
                .map(SpffUserRelations::getUserId)
                .collect(Collectors.toList());

        // 批量查询粉丝用户信息
        List<SpffUsers> followers = spffUsersService.selectSpffUsersByIds(followerUserIds);

        // 构建分页结果
        Map<String, Object> result = new HashMap<>();
        result.put("list", followers);
        result.put("total", total);
        result.put("page", page);
        result.put("pages", total == 0 ? 0 : (int) Math.ceil((double) total / pageSize));
        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult getFollowing(Long userId, Integer page, Integer pageSize) {
        SpffUsers user = spffUsersService.selectSpffUsersById(userId);
        if (user == null) {
            return AjaxResult.error("用户不存在");
        }

        // 查询关注列表
        Map<String, Object> params = new HashMap<>();
        params.put("userId", userId);
        params.put("offset", (page - 1) * pageSize);
        params.put("pageSize", pageSize);
        
        List<SpffUserRelations> relations = spffUserRelationsService.selectFollowingByUserId(params);
        int total = spffUserRelationsService.countFollowingByUserId(userId);

        if (relations.isEmpty()) {
            Map<String, Object> result = new HashMap<>();
            result.put("list", new ArrayList<>());
            result.put("total", total);
            result.put("page", page);
            result.put("pages", total == 0 ? 0 : (int) Math.ceil((double) total / pageSize));
            return AjaxResult.success(result);
        }

        // 获取被关注用户ID列表
        List<Long> followingUserIds = relations.stream()
                .map(SpffUserRelations::getTargetUserId)
                .collect(Collectors.toList());

        // 批量查询被关注用户信息
        List<SpffUsers> following = spffUsersService.selectSpffUsersByIds(followingUserIds);

        // 构建分页结果
        Map<String, Object> result = new HashMap<>();
        result.put("list", following);
        result.put("total", total);
        result.put("page", page);
        result.put("pages", total == 0 ? 0 : (int) Math.ceil((double) total / pageSize));
        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult getUserStats(Long userId) {
        SpffUsers user = spffUsersService.selectSpffUsersById(userId);
        if (user == null) {
            return AjaxResult.error("用户不存在");
        }

        Map<String, Object> stats = new HashMap<>();
        stats.put("userId", userId);
        stats.put("followerCount", user.getFollowerCount());
        stats.put("followingCount", user.getFollowingCount());
        stats.put("videoCount", user.getVideoCount());
        stats.put("likeCount", user.getLikeCount());
        stats.put("isVerified", user.getIsVerified());

        return AjaxResult.success(stats);
    }

    @Override
    public AjaxResult getUserList(Integer page, Integer pageSize, String keyword) {
        return null;
    }

    @Override
    public AjaxResult searchUsers(String keyword, Integer page, Integer pageSize) {
        return null;
    }

//    @Override
//    public Result searchUsers(String keyword, Integer page, Integer pageSize) {
//        if (keyword == null || keyword.trim().isEmpty()) {
//            return Result.fail("搜索关键词不能为空");
//        }
//
//        int offset = (page - 1) * pageSize;
//        List<SpffUsers> users = spffUsersService.searchUsers(keyword, offset, pageSize);
//        int total = spffUsersService.countSearchUsers(keyword);
//
//        Map<String, Object> result = new HashMap<>();
//        result.put("list", users);
//        result.put("total", total);
//        result.put("page", page);
//        result.put("pages", total == 0 ? 0 : (int) Math.ceil((double) total / pageSize));
//
//        return Result.ok(result);
//    }

    @Override
    public AjaxResult getUserByIds(List<Long> userIds) {
        return null;
    }

    @Override
    public AjaxResult updateUserStatus(Long userId, String status) {
        return null;
    }

    @Override
    public AjaxResult updateUserVerification(Long userId, String isVerified) {
        return null;
    }

    @Override
    public AjaxResult recommendUsers(Long userId, Integer pageSize) {
        return null;
    }

    @Override
    public AjaxResult isFollowing(Long userId, Long targetUserId) {
        if (userId.equals(targetUserId)) {
            return AjaxResult.error("不能关注自己");
        }

        SpffUserRelations relation = spffUserRelationsService.selectByUserIdAndTargetUserId(userId, targetUserId, 1);
        
        Map<String, Object> result = new HashMap<>();
        result.put("isFollowing", relation != null);
        
        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult updateLoginTime(Long userId) {
        return null;
    }

    @Override
    public AjaxResult updatePassword(Long userId, String oldPassword, String newPassword) {
        SpffUsers user = spffUsersService.selectSpffUsersById(userId);
        if (user == null) {
            return AjaxResult.error("用户不存在");
        }

        if (!user.getPassword().equals(oldPassword)) {
            return AjaxResult.error("原密码错误");
        }

        user.setPassword(newPassword);
        spffUsersService.updateSpffUsers(user);

        return AjaxResult.success("密码修改成功");
    }

    @Override
    public AjaxResult uploadAvatar(Long userId, String avatarUrl) {
        SpffUsers user = spffUsersService.selectSpffUsersById(userId);
        if (user == null) {
            return AjaxResult.error("用户不存在");
        }

        user.setAvatar(avatarUrl);
        spffUsersService.updateSpffUsers(user);
        
        return AjaxResult.success("头像上传成功");
    }

    @Override
    public AjaxResult logout(HttpSession session) {
        return null;
    }

    @Override
    public AjaxResult checkUserExists(String username) {
        if (username == null || username.trim().isEmpty()) {
            return AjaxResult.error("用户名不能为空");
        }
        
        SpffUsers user = spffUsersService.selectSpffUsersByUsername(username);
        Map<String, Object> result = new HashMap<>();
        result.put("exists", user != null);
        
        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult register(SpffUsers user) {
        if (user == null) {
            return AjaxResult.error("用户信息不能为空");
        }
        
        // 验证必填字段
        if (user.getUsername() == null || user.getUsername().trim().isEmpty()) {
            return AjaxResult.error("用户名不能为空");
        }
        if (user.getPassword() == null || user.getPassword().trim().isEmpty()) {
            return AjaxResult.error("密码不能为空");
        }
        if (user.getEmail() == null || user.getEmail().trim().isEmpty()) {
            return AjaxResult.error("邮箱不能为空");
        }
        
        // 检查用户名是否已存在
        SpffUsers existingUser = spffUsersService.selectSpffUsersByUsername(user.getUsername());
        if (existingUser != null) {
            return AjaxResult.error("用户名已存在");
        }
        
        // 检查邮箱是否已被使用
        SpffUsers existingEmailUser = spffUsersService.selectSpffUsersByEmail(user.getEmail());
        if (existingEmailUser != null) {
            return AjaxResult.error("该邮箱已被注册");
        }
        
        // 设置默认值
        if (user.getNickname() == null || user.getNickname().trim().isEmpty()) {
            user.setNickname(user.getUsername());
        }
        user.setFollowerCount(0L);
        user.setFollowingCount(0L);
        user.setVideoCount(0L);
        user.setLikeCount(0L);
        user.setIsVerified(0);
        user.setStatus(1); // 正常状态
        user.setGender(0); // 未知
        
        // 保存用户
        int result = spffUsersService.insertSpffUsers(user);
        if (result > 0) {
            log.info("用户注册成功，用户名：{}", user.getUsername());
            return AjaxResult.success("注册成功");
        } else {
            return AjaxResult.error("注册失败，请稍后重试");
        }
    }

    @Override
    public AjaxResult resetPassword(String email, String newPassword) {
        if (email == null || email.trim().isEmpty()) {
            return AjaxResult.error("邮箱不能为空");
        }
        if (newPassword == null || newPassword.trim().isEmpty()) {
            return AjaxResult.error("新密码不能为空");
        }
        
        // 查找用户
        SpffUsers user = spffUsersService.selectSpffUsersByEmail(email);
        if (user == null) {
            return AjaxResult.error("该邮箱未注册");
        }
        
        // 更新密码
        user.setPassword(newPassword);
        int result = spffUsersService.updateSpffUsers(user);
        
        if (result > 0) {
            log.info("用户重置密码成功，邮箱：{}", email);
            return AjaxResult.success("密码重置成功");
        } else {
            return AjaxResult.error("密码重置失败，请稍后重试");
        }
    }

//    @Override
//    public Result sign() {
//        // 1.获取当前登录用户
//        Long userId = UserHolder.getUser().getId();
//        // 2.获取日期
//        LocalDateTime now = LocalDateTime.now();
//        // 3.拼接key
//        String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
//        String key = USER_SIGN_KEY + userId + keySuffix;
//        // 4fMo.获取今天是本月的第几天
//        int dayOfMonth = now.getDayOnth();
//        // 5.写入Redis SETBIT key offset 1
//        stringRedisTemplate.opsForValue().setBit(key, dayOfMonth - 1, true);
//        return Result.ok();
//    }

//    @Override
//    public Result signCount() {
//        // 1.获取当前登录用户
//        Long userId = UserHolder.getUser().getId();
//        // 2.获取日期
//        LocalDateTime now = LocalDateTime.now();
//        // 3.拼接key
//        String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
//        String key = USER_SIGN_KEY + userId + keySuffix;
//        // 4.获取今天是本月的第几天
//        int dayOfMonth = now.getDayOfMonth();
//        // 5.获取本月截止今天为止的所有的签到记录，返回的是一个十进制的数字 BITFIELD sign:5:202203 GET u14 0
//        List<Long> result = stringRedisTemplate.opsForValue().bitField(
//                key,
//                BitFieldSubCommands.create()
//                        .get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0)
//        );
//        if (result == null || result.isEmpty()) {
//            // 没有任何签到结果
//            return Result.ok(0);
//        }
//        Long num = result.get(0);
//        if (num == null || num == 0) {
//            return Result.ok(0);
//        }
//        // 6.循环遍历
//        int count = 0;
//        while (true) {
//            // 6.1.让这个数字与1做与运算，得到数字的最后一个bit位  // 判断这个bit位是否为0
//            if ((num & 1) == 0) {
//                // 如果为0，说明未签到，结束
//                break;
//            }else {
//                // 如果不为0，说明已签到，计数器+1
//                count++;
//            }
//            // 把数字右移一位，抛弃最后一个bit位，继续下一个bit位
//            num >>>= 1;
//        }
//        return Result.ok(count);
//    }


    //注册模块
//    private User createUserWithPhone(String phone) {
//        // 1.创建用户
//        User user = new User();
//        user.setPhone(phone);
//        user.setNickName(USER_NICK_NAME_PREFIX + RandomUtil.randomString(10));
//        // 2.保存用户
//        save(user);
//        return user;
//    }
}
